package jeeobserver.utilities;

import java.util.Date;

public class MathUtilities {

	public static double percent(double current, double total) {
		double percentage;

		if (total > 0 && current > 0) {
			percentage = new Double(current) / new Double(total);
		} else {
			if (current > total) {
				percentage = 1.0d;
			} else {
				percentage = 0.0d;
			}
		}

		return percentage;
	}

	public static double avg(double count1, double value1, double count2, double value2) {
		return ((count1 * value1) + (count2 * value2)) / (count1 + count2);
	}

	public static double avg(double count, double value) {
		return value / count;
	}

	public static Date max(Date value1, Date value2) {
		if (value1 == null && value2 != null) {
			return value2;
		} else if (value1 != null && value2 == null) {
			return value1;
		} else if (value1.after(value2)) {
			return value1;
		}

		return value2;
	}

	public static Date min(Date value1, Date value2) {

		if (value1 == null && value2 != null) {
			return value2;
		} else if (value1 != null && value2 == null) {
			return value1;
		} else if (value1.before(value2)) {
			return value1;
		}

		return value2;
	}

	public static double trendIndex(double average, double predicted) {
		double difference = (predicted - average);

		boolean negative = false;

		if (difference < 0) {
			negative = true;
		}


		//if (average > 0) {
			//trendIndex = Math.log(((Math.abs(difference)) * 100 / average) + 1);
			//trendIndex = Math.log(((Math.abs(difference)) * 25 / average) + 1);
		double trendIndex = Math.abs(difference)  / Math.abs(average);
		//}

		if (negative) {
			trendIndex = trendIndex * -1;
		}

		return trendIndex;
	}

	public static double linearRegression(double values[][],int index, long x) {

		if (values.length <= 0) {
			return 0;
		}

		if (values.length == 1) {
			return values[0][index];
		}

		//Simple regression
		double sumX = 0;

		double sumXX = 0;

		double sumYY = 0;

		double sumY = 0;

		double sumXY = 0;
		double xbar = 0;
		double ybar = 0;


		long n = 0;

		for (int i = 0; i < values.length; i++) {

			if (n == 0) {
				xbar = values[i][0];
				ybar = values[i][1];
			} else {
				final double fact1 = 1.0 + n;
				final double fact2 = n / (1.0 + n);
				final double dx = values[i][0] - xbar;
				final double dy = values[i][index] - ybar;
				sumXX += dx * dx * fact2;
				sumYY += dy * dy * fact2;
				sumXY += dx * dy * fact2;
				xbar += dx / fact1;
				ybar += dy / fact1;
			}

			sumX += values[i][0];
			sumY += values[i][index];

			n++;
		}

		//calculate slope

		double slope = sumXY / sumXX;

		double intercept = (sumY - slope * sumX) / n;

		return intercept + slope * x;
	}

	public static double deviation(double values[][], int index) {

		if (values.length <= 1) {
			return 0;
		}

		//Mean
		long sum = 0;

		for (int i = 0; i < values.length; i++) {
			sum += values[i][index];
		}

		long mean = sum / values.length;

		//SquareSum
		long squareSum = 0;

		for (int i = 0; i < values.length; i++) {
			squareSum += Math.pow(values[i][index] - mean, 2);
		}

		return Math.sqrt((squareSum) / (values.length - 1));
	}

	public static double deviation(double values[]) {
		//Mean
		long sum = 0;

		for (int i = 0; i < values.length; i++) {
			sum += values[i];
		}

		long mean = sum / values.length;

		//SquareSum
		long squareSum = 0;

		for (int i = 0; i < values.length; i++) {
			squareSum += Math.pow(values[i] - mean, 2);
		}

		return  Math.sqrt((squareSum) / (values.length - 1));

	}
}
